package com.unknownman.block.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.lianziyou.chain.common.api.CommonPage;
import com.lianziyou.chain.common.api.CommonResult;
import com.unknownman.block.constants.ChainContractConstants;
import com.unknownman.block.dto.ChainContractComposition;
import com.unknownman.block.entity.TChainConfig;
import com.unknownman.block.entity.TContractConfig;
import com.unknownman.block.mapper.TChainConfigMapper;
import com.unknownman.block.service.TChainConfigService;
import com.unknownman.block.service.TContractConfigService;
import com.unknownman.block.transaction.InitChainTranSubscribe;
import javax.annotation.PostConstruct;
import org.cloud.entity.LoginUserDetails;
import org.cloud.exception.BusinessException;
import org.cloud.utils.CollectionUtil;
import org.cloud.utils.CommonUtil;
import org.cloud.utils.SpringContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * NFT链配置 服务实现类
 * </p>
 *
 * @author xhy
 * @since 2021-10-16
 */
@Service
public class TChainConfigServiceImpl extends ServiceImpl<TChainConfigMapper, TChainConfig> implements TChainConfigService {

    @Autowired
    private TContractConfigService contractConfigService;

    @Lazy
    @Autowired
    private InitChainTranSubscribe initChainTranSubscribe;

    @Override
    public CommonPage<TChainConfig> findListByPage(Integer page, Integer limit, String orderBy, QueryWrapper<TChainConfig> queryWrapper) {
        if (StringUtils.isEmpty(orderBy)) {
            PageHelper.startPage(page, limit);
        } else {
            PageHelper.startPage(page, limit, orderBy);
        }
        List<TChainConfig> list = baseMapper.selectList(queryWrapper);
        return CommonPage.restPage(list);
    }

    @Override
    public List<ChainContractComposition> getChainContractCompositionList(boolean onlyEnable) {
        ChainContractConstants.ChainStatusConstants chainStatus = null;
        ChainContractConstants.ContractStatusConstants contractStatus = null;
        if (onlyEnable) {
            chainStatus = ChainContractConstants.ChainStatusConstants.NORMAL;
            contractStatus = ChainContractConstants.ContractStatusConstants.NORMAL;
        }
        List<TChainConfig> chainConfigList = getListByStatus(chainStatus);
        ArrayList<ChainContractComposition> rs = new ArrayList<>();
        if (CollectionUtil.single().isNotEmpty(chainConfigList)) {
            for (TChainConfig chainConfig : chainConfigList) {
                List<TContractConfig> contractConfigList = contractConfigService.getListByChainConfigId(chainConfig.getChainConfigId(),
                    contractStatus);
                ChainContractComposition chainContractComposition = new ChainContractComposition(chainConfig, contractConfigList);
                rs.add(chainContractComposition);
            }
        }
        return rs;
    }

    @Override
    public List<TChainConfig> getListByStatus(ChainContractConstants.ChainStatusConstants chainStatus) {
        QueryWrapper<TChainConfig> queryWrapper = new QueryWrapper<>();
        if (chainStatus != null) {
            queryWrapper.eq("chain_status", chainStatus.getStatus());
        }
        return list(queryWrapper);
    }

    @Override
    public ChainContractComposition getChainContractCompositionById(Long id) {
        TChainConfig chainConfig = getById(id);
        ChainContractComposition rs = new ChainContractComposition(chainConfig);
        if (chainConfig != null) {
            List<TContractConfig> contractConfigList = contractConfigService.getListByChainConfigId(chainConfig.getChainConfigId(), null);
            rs.setContractList(contractConfigList);
        }
        return rs;
    }

    @Override
    public ChainContractComposition getChainContractCompositionByChainSymbol(String symbol) {
        QueryWrapper<TChainConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("chain_symbol", symbol);
        TChainConfig chainConfig = getOne(queryWrapper);
        ChainContractComposition rs = new ChainContractComposition(chainConfig);
        if (chainConfig != null) {
            List<TContractConfig> contractConfigList = contractConfigService.getListByChainConfigId(chainConfig.getChainConfigId(), null);
            rs.setContractList(contractConfigList);
        }
        return rs;
    }

    @Override
    public int updateLastBlock(Long id, Long block, boolean success) {
        return baseMapper.updateLastBlock(id, block, success);
    }


    @Override
    public CommonResult updateChain(TChainConfig config) throws BusinessException {
        TChainConfig chainConfig = baseMapper.selectById(config.getChainConfigId());
        if (ObjectUtils.isEmpty(chainConfig)) {
            throw new BusinessException("链配置不存在");
        }
        if (StringUtils.isEmpty(config.getRpcAddress())) {
            throw new BusinessException("RPC地址为空");
        }
        if (StringUtils.isEmpty(config.getChainSymbol())) {
            throw new BusinessException("部署链为空");
        }
        if (StringUtils.isEmpty(config.getChainId())) {
            throw new BusinessException("链ID为空");
        }
        LoginUserDetails loginUser = CommonUtil.single().getLoginUser();
        config.setUpdateBy(loginUser.getUsername());
        int insert = baseMapper.updateById(config);
        if (insert == 0) {
            throw new BusinessException("修改失败");
        }
        initChainTranSubscribe.clearSubscribe(chainConfig.getChainConfigId());
        return CommonResult.success();
    }

    @Override
    public CommonResult addChain(TChainConfig config) throws BusinessException {
        if (StringUtils.isEmpty(config.getRpcAddress())) {
            throw new BusinessException("RPC地址为空");
        }
        if (StringUtils.isEmpty(config.getChainSymbol())) {
            throw new BusinessException("部署链为空");
        }
        if (StringUtils.isEmpty(config.getChainId())) {
            throw new BusinessException("链ID为空");
        }
        LoginUserDetails loginUser = CommonUtil.single().getLoginUser();
        config.setCreateBy(loginUser.getUsername());
        int insert = baseMapper.insert(config);
        if (insert == 0) {
            throw new BusinessException("修改失败");
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult updateStatus(Long chainConfigId, Integer status) throws BusinessException {
        TChainConfig chainConfig = baseMapper.selectById(chainConfigId);
        if (ObjectUtils.isEmpty(chainConfig)) {
            throw new BusinessException("链配置不存在");
        }
        TChainConfig config = new TChainConfig();
        config.setChainConfigId(chainConfigId);
        config.setChainStatus(status);
        int update = baseMapper.updateById(config);
        if (update == 0) {
            throw new BusinessException("更新失败");
        }
        initChainTranSubscribe.clearSubscribe(chainConfig.getChainConfigId());
        return CommonResult.success();
    }
}
